import re
import time

import requests
from bs4 import BeautifulSoup
from lxml import etree
from enum import Enum
from ai.utils import utils_file
from selenium.webdriver.common.by import By
import traceback
import logging
from ai import AiConstant
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import seleniumwire
from seleniumwire import webdriver as wire_webdriver

log_path = utils_file.join_path('./ximalaya.log')

logger = AiConstant.AI_LOGGER(log_path)


def if_response_content_is_none(response):
    if response.content is None:
        logger.info('response.content为None,加载数据失败')
        return True
    return False


def write_to_html(data, file_name):
    with open(file_name, 'w', encoding='utf-8') as f:
        f.write(data)


def get_ids(datas):
    """
    datas: [strs]:str_list or str:str
    return : [ids]:list
    """
    if isinstance(datas, list):
        return [x.split('/')[-1] for x in datas]
    elif isinstance(datas, str):
        return [datas.split('/')[-1]]


class REQUEST_METHOD(Enum):
    GET = 1
    POST = 2


def send_request(src, headers, method: REQUEST_METHOD = REQUEST_METHOD.GET):
    """
    发送请求, 如果顺利得到response并没有爆出任何错误,同时状态码为200, 则正常返回, 否则给出失败提示,
    需要调用者自行决定是否进行成功提示, 该函数不提供
    """
    response = None
    try:
        if method == REQUEST_METHOD.GET:
            response = requests.get(src, headers=headers)
        elif method == REQUEST_METHOD.POST:
            response = requests.post(src, headers=headers)
        if not hasattr(response, 'status_code'):
            raise RuntimeError()
        if not (response.status_code == 200 or response.status_code == 206):
            raise RuntimeError()
    except Exception as e:
        if hasattr(response, 'status_code'):
            logger.error(f"请求失败{e},code:{response.status_code}")
        else:
            logger.error(f"请求失败{e}")
        traceback.print_exc()
        return None
    return response


def interceptor(request):
    # 修改请求头中的User-Agent
    request.headers[
        "Cookie"] = 'll="118371"; bid=Fsbe9sfmWeE; douban-fav-remind=1; _pk_id.100001.4cf6=418738468fffe252.1687100016.; __yadk_uid=QALpMKXECMQyz7KgtiAoZB3f9sDCr7wk; _vwo_uuid_v2=D22F58820969D590BFCDCC8325B7D22D5|2ef8c52d900cdee29e6c7a70634e2fd9; viewed="35121203_36142067_36206397"; _ga=GA1.1.1410860224.1696751048; _ga_Y4GN1R87RG=GS1.1.1696751048.1.1.1696751067.0.0.0; ap_v=0,6.0; _pk_ref.100001.4cf6=%5B%22%22%2C%22%22%2C1696767285%2C%22https%3A%2F%2Fm.douban.com%2F%22%5D; _pk_ses.100001.4cf6=1; ct=y; dbcl2="231323398:RLeLw+DqlGM"; ck=pxhW; push_noty_num=0; push_doumail_num=0',


def handle_cookie__to_dict(string: str):
    res = {}
    items = string.strip().split(';')
    for item in items:
        mm = item.strip().split('=')
        for i in range(len(mm)):
            m = mm[i]
            print(m)
            if m.startswith('\'') or m.startswith('\"'):
                m = m[1:]
            if m.endswith('\"') or m.endswith('\''):
                m = m[:-1]
            mm[i] = m

        res[mm[0]] = mm[1]
    return res


def login_do_douban(username_input='13937825104', password_input='Gxl2236035.'):
    url = "https://accounts.douban.com/passport/login?source=movie"
    driver = webdriver.Chrome()
    driver.get(url)
    driver.implicitly_wait(1)
    user_name_xpath = '/html/body/div[1]/div[3]/div[2]/div/div[2]/div[1]/div[2]/div/input'
    user_pwd_xpath = '/html/body/div[1]/div[3]/div[2]/div/div[2]/div[1]/div[3]/div/input'
    login_a_xpath = '/html/body/div[1]/div[3]/div[2]/div/div[2]/div[1]/div[4]/a'
    username_id = 'username'
    pwd_id = 'password'
    a_id = '#account > div.login-wrap > div.login-right > div > div.account-tabcon-start > div.account-form > div.account-form-field-submit > a'
    # username = browser.find_element(by=By.ID, value=username_id)
    # username.send_keys(username_input)
    # password = browser.find_element(by=By.ID, value=pwd_id)
    # password.send_keys(password_input)
    # login_a = browser.find_element(by=By.XPATH, value=login_a_xpath)
    # login_a.click()
    username = driver.find_element(By.CSS_SELECTOR, "#username")
    # 填入用户名
    username.send_keys("your_username")
    # 通过js_path找到密码输入框
    password = driver.find_element_by_js_path("document.getElementById('password')")
    # 填入密码
    password.send_keys("your_password")

    driver.implicitly_wait(5)
    html = driver.page_source
    return html


def get_full_html_from_url(url):
    options = Options()
    options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
    driver = webdriver.Chrome(options=options)
    driver.get(url)
    driver.implicitly_wait(0.5)
    html = driver.page_source
    return html, driver


def do_a_click_to_a_driver(driver: selenium.webdriver.Chrome, button_location_xpath):
    """"""
    button = driver.find_element(By.XPATH, button_location_xpath)
    button.click()
    driver.implicitly_wait(2.5)
    time.sleep(2.5)
    # 获取网页源码
    html = driver.page_source
    return html, driver


def handle_xpath(html_text: str, xpath):
    tree = etree.HTML(html_text)
    datas = tree.xpath(xpath)
    return datas


def sub_handle_xpath(tree, xpath):
    try:
        datas = tree.xpath(xpath)
        if len(datas) == 0 or len(datas[-1]) == 0:
            raise RuntimeError()
        return datas
    except Exception as e:
        logger.info('xpath处理失败')
        return None


def join_path(path1, path2):
    if path1 is None or path2 is None or len(path1) == 0 or len(path2) == 0:
        return ""
    while path1[-1] == '/' or path1[-1] == '\\':
        path1 = path1[:-1]
    while path2[0] == '/' or path2[0] == '\\':
        path2 = path2[1:]
    return f'{path1}/{path2}'


def join_path_plus(*args):
    lens = len(args)
    if lens == 0:
        return ""
    path = args[0]
    for i in range(1, lens):
        path = join_path(path, args[i])
    return path


def clean_filename(filename):
    # 移除非法字符
    cleaned_filename = re.sub(r'[\/:*?"<>|]', '-', filename)

    # 截断文件名，以确保它在不同系统下都有效
    cleaned_filename = cleaned_filename[:255]

    return cleaned_filename


class FileType(Enum):
    HTML = 1,
    XML = 2,


def text2special_file(text, file_type: FileType = FileType.HTML):
    if file_type == FileType.HTML:
        try:
            tree = etree.HTML(text)
        except Exception as e:
            logger.info('text->html失败')
            return None
        return tree


def if_json_data_is_none(json_data):
    if json_data is None:
        logger.info('json_data is None, 未获取到json数据')
        return True
    return False


def get_name_by_rules(id, album_id, title, with_album_id, with_title):
    adds = []
    if with_album_id:
        adds.append(album_id)
    if with_title:
        title = clean_filename(title)
        adds.append(title)
    name = str(id)
    for item in adds:
        name = name + '_' + item
    name = name + '.wav'
    return name
